package core

import (
	// "bytes"
	"compress/gzip"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	// "regexp"
	// "reflect"
	"strings"
	// "code.google.com/p/mahonia"
	// "github.com/gocolly/colly"
	// "github.com/spf13/viper"
)

/**
* 翻译单词: thing
* 请求url: https://fanyi.baidu.com/v2transapi?from=en&to=zh
* FormData: from=en&to=zh&query=thing&transtype=realtime&simple_means_flag=3&sign=319631.958&token=afe9f79a5799dab64fb4c0cd9c7d8ac7&domain=common
*     sign: 调用JS: index_xxxxxxx.js:function e(n)计算得到
* JS解释器: https://github.com/robertkrimen/otto
 */

func Post(url string, data io.Reader) map[string]interface{} {
	// 创建请求
	req, err := http.NewRequest("POST", url, data)
	ChkErr(err)
	req.Header.Set("Host", "fanyi.baidu.com")
	req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0")
	req.Header.Set("Accept", "application/json, text/javascript, */*; q=0.01")
	req.Header.Set("Accept-Language", "en-US,en;q=0.5")
	req.Header.Set("Accept-Encoding", "gzip, deflate, br")
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
	req.Header.Set("X-Requested-With", "XMLHttpRequest")
	req.Header.Set("Content-Length", "4")
	req.Header.Set("Origin", "https://fanyi.baidu.com")
	req.Header.Set("DNT", "1")
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Referer", "https://fanyi.baidu.com/?aldtype=16047")
	req.Header.Set("Cookie", "BAIDUID=6ECDFC49AEB84C1245032272CD1565E7:SL=0:NR=50:FG=1; BIDUPSID=9D04ADCD1E50E5858681EE758CCAAA6C; PSTM=1537692700; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1585290964; from_lang_often=%5B%7B%22value%22%3A%22de%22%2C%22text%22%3A%22%u5FB7%u8BED%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D; to_lang_often=%5B%7B%22value%22%3A%22jp%22%2C%22text%22%3A%22%u65E5%u8BED%22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%5D; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; MCITY=-300%3A; BDUSS=k1ldmhQaXUyUVM2N1UxSzFTNUUyQzEzN0czZ1VOb053LVNwMnRIVU16NnE5MGhlSUFBQUFBJCQAAAAAAAAAAAEAAADMOkIGU2Fyb3RoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKpqIV6qaiFeY; BDSFRCVID=Ew_OJeC62rzLqwcuw9_Irp_nwmHjQyoTH6aoYceoeFJFE2BQUqg0EG0P_U8g0Ku-DcdzogKK3mOTH4-F_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tJAq_D0hfIP3fP36q45Mq4tHeP_8tURZ5mAqoDbzWfDWhPKxXT3M-lv3X4RMBMn3yIrnaIQq54LajMjgKMTsQP_YbR6Q25c43bRTMbLy5KJvfJ_Gjf7IhP-UyNbLWh37JPjlMKoaMp78jR093JO4y4Ldj4oxJpOJ5JbMopCafDDbbD0xj6LBePtjMfbWetoQ265tWjrJabC3HP8xXU6qLT5XeHQMbjONbRRyQJotyIbFOnr-MUOqjp0njxQyBbQZ3NIOb-JYKRKafU3k5fonDh8q2a7MJUntKHcAoj6O5hvvhn6O3MAMqfKmDloOW-TB5bbPLUQF5l8-sq0x0bOte-bQXH_EqT_eJJKJ_Iv5b-0_qbTkbn7Wq4tehHRu5xo9WDTmLh6nWRobqnoG3Pjl-tDRj-TiabcgaKOy-pPKKR74spvS3pQFy--L5Njf2t703mkjbU7Dfn02OPKzqt62W-4syP4e2xRnWnPLKfA-b4ncjRcTehoM3xI8LNj405OTbIFO0KJzJCFKMKLGjTtKe5PObqOKa4AXMDOQsJOOa6rjDCvS3Urcy4Ldht7mhRckMC7t-DbeJlCKfR3IhfRvD--g3-7QhPnHajnx-lcPQJnxVMQ_bf--QfbQ0hOhqP-jW5Ta3q-5yR7JOpkxbUnxy5KUQRPH-Rv92DQMVU52QqcqEIQHQT3m5-5bbN3ut6IetnkJ_DI-fbj8J6rIMnt_-P4DePofyMRZ5mAqotoLBPjbHP56eqnzKR8mhlJLBPTIMCOnaIQqaMTjeJ7NQx6PQjDY0JoDK5O43bRTMMKy5KJvfj6e-PO0hP-UyNbLWh37JPjlMKoaMp78jR093JO4y4Ldj4oxJpOJ5JbMopCafJOKHICRjTDhjMK; H_PS_PSSID=1421_31326_21124_31428_31342_30910_31464_30824_31164_31473; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1587776080; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; delPer=0; PSINO=6; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0")
	req.Header.Set("Pragma", "no-cache")
	req.Header.Set("Cache-Control", "no-cache")
	req_body, err := req.GetBody()
	ChkErr(err)
	req_data, err := ioutil.ReadAll(req_body)
	ChkErr(err)
	Log.Debug("=> [POST] %s  `%s`", req.URL.String(), req_data)

	// 发送请求, 获取响应
	cli := &http.Client{}
	resp, err := cli.Do(req)
	ChkErr(err)
	defer resp.Body.Close()
	body := resp.Body
	if strings.Compare(resp.Header.Get("Content-Encoding"), "gzip") == 0 {
		body, err = gzip.NewReader(body)
		ChkErr(err)
	}
	resp_bytes, err := ioutil.ReadAll(body)
	ChkErr(err)

	// 判断响应错误
	m := make(map[string]interface{})
	json.Unmarshal(resp_bytes, &m)
	Log.Debug("<= [Resp] `%s`", m)
	return m
}

/** 获取单词建议(单词补全) */
func Suggestion(k string) []map[string]string {
	m := Post("https://fanyi.baidu.com/sug", strings.NewReader("kw="+k))
	if m["errno"] != 0.0 {
		panic(ErrNew(fmt.Sprintf("请求失败: %#v(%#v)", m["errmsg"], m["errno"])))
	}

	data := m["data"].([]interface{})
	list := make([]map[string]string, 0, 5)
	for _, d := range data {
		kv := d.(map[string]interface{})
		list = append(list, map[string]string{
			"k": kv["k"].(string),
			"v": kv["v"].(string),
		})
	}
	return list
}

/** 检测语言类型 */
func LanguageDetect(s string) string {
	m := Post("https://fanyi.baidu.com/langdetect", strings.NewReader("query="+s))
	no := m["error"]
	if no != 0.0 {
		panic(ErrNew(fmt.Sprintf("请求失败: %#v(%#v)", m["errmsg"], m["errno"])))
	}
	return m["lan"].(string)
}

func n(dat int32, op string) int32 {
	for t := 0; t < len(op)-2; t += 3 {
		a := int32(op[t+2])
		if a >= 'a' {
			a -= 0x57
		} else {
			a -= '0'
		}
		if op[t+1] == '+' {
			a = int32(uint32(dat) >> uint(a))
		} else {
			a = int32(uint32(dat) << uint(a))
		}
		if op[t] == '+' {
			dat += int32(uint32(a) & 0xFFFFFFFF)
		} else {
			dat ^= a
		}
	}
	return dat
}

/** 计算签名. 实现index_xxxxxxx.js:function e(n)函数 */
func sign(str string) string {
	strlen := len(str)
	if strlen > 30 {
		str = str[0:10] + str[strlen/2-5:strlen/2+5] + str[strlen-10:strlen]
		strlen = len(str)
	}
	m := int32(320305)
	s := int32(131321201)
	p := m
	for b := 0; b < strlen; b++ {
		p += int32(str[b])
		p = n(p, "+-a^+6")
	}
	p = n(p, "+-3^+b+-f") ^ s
	if p < 0 {
		p = int32((uint32(p)&0x7FFFFFFF + 0x80000000) % 1000000)
	} else {
		p %= 1000000
	}
	return fmt.Sprintf("%d.%d", p, p^m)
}

/** 翻译 */
func TransAPIv2(from string, to string, str string) map[string]interface{} {
	req := "transtype=realtime"
	req += "&simple_means_flag=3"
	req += "&domain=common"
	req += "&token=afe9f79a5799dab64fb4c0cd9c7d8ac7"
	req += "&from=" + from
	req += "&to=" + to
	req += "&query=" + str
	req += "&sign=" + sign(str)
	m := Post("https://fanyi.baidu.com/v2transapi", strings.NewReader(req))
	no := m["error"]
	if no != nil && no != 0.0 {
		panic(ErrNew(fmt.Sprintf("请求失败(%#v), req:%#v", m["error"], req)))
	}

	logid := m["logid"]
	Log.Info("logid: %#v", logid)
	return m
}
